<script lang="ts" setup>
import {ref, watch} from "vue";
import {ElMessageBox, ElMessage} from "element-plus";
import type {Field} from "@/type/toolLibs/protocol";

const props = defineProps<{
  data: Field[];
  editMode: boolean;
}>();
console.log("收到父组件数据： ", props.data)
// 定义事件
const emit = defineEmits<{
  'update:data': [value: Field[]];
  'open-editor': [field: Field];
}>();


// 递归清理函数：移除所有object和array类型字段的size属性
const cleanupFields = (fields: Field[]) => {
  fields.forEach(field => {
    // 如果是object或array类型，移除size属性
    if (field.type === 'object' || field.type === 'array') {
      delete field.size;
      // 递归处理子字段
      if (field.fields) {
        cleanupFields(field.fields);
      }
    }
  });
};

// 创建响应式副本
const localData = ref<Field[]>(props.data);
// 初始清理
cleanupFields(localData.value);
console.log("localData", localData.value)

// 监听props变化，同步到本地数据
watch(() => props.data, (newData) => {
  localData.value = newData;
  // 数据变化时清理
  cleanupFields(localData.value);
  console.log("localData.value", localData.value);
}, {deep: true});

// 当前编辑字段
const editDialogVisible = ref(false);
const form = ref<Field>({name: "", type: "u8", size: 1, description: ""});
let editTarget: Field | null = null;
// 存储当前编辑字段的同级字段
let currentParentFields: Field[] = [];

// 监听表单类型变化，设置对应的默认size
watch(() => form.value.type, (newType) => {
  if (newType === 'object' || newType === 'array') {
    form.value.size = undefined;
  } else if (newType === 'u8') {
    form.value.size = 1;
  } else if (newType === 'u16') {
    form.value.size = 2;
  } else if (newType === 'u32') {
    form.value.size = 4;
  }
});

// 展开控制
const expanded = ref<Record<string, boolean>>({});


// 打开编辑框
const openEditor = (field: Field) => {
  if (!props.editMode) {
    return;
  }
  editTarget = field;
  form.value = {...field};
  // 查找当前字段的同级字段（在当前组件的localData中查找）
  currentParentFields = localData.value;
  // 根据类型设置正确的size
  if (form.value.type === 'object' || form.value.type === 'array') {
    form.value.size = undefined;
  } else if (form.value.type === 'u8') {
    form.value.size = 1;
  } else if (form.value.type === 'u16') {
    form.value.size = 2;
  } else if (form.value.type === 'u32') {
    form.value.size = 4;
  } else if (form.value.type === 'string') {
    form.value.size = 2;
  }
  editDialogVisible.value = true;
};

// 保存
const saveField = () => {
  if (editTarget) {
    // 保存前处理：如果是object或array类型，确保没有size属性
    const saveData = {...form.value};
    if (saveData.type === 'object' || saveData.type === 'array') {
      delete saveData.size;
    }
    Object.assign(editTarget, saveData);
    // 清理所有字段，确保没有遗漏
    cleanupFields(localData.value);
    // 通知父组件数据更新
    emit('update:data', localData.value);
  }
  editDialogVisible.value = false;
};

// 删除字段
const removeField = (list: Field[], idx: number) => {
  ElMessageBox.confirm("确定删除该字段吗？").then(() => {
    list.splice(idx, 1);
    // 通知父组件数据更新
    emit('update:data', localData.value);
  });
};

// 添加同级字段
const addSiblingField = (list: Field[], index: number) => {
  // 为新字段生成唯一名称
  const existingNames = list.map(f => f.name);
  let counter = 1;
  let newName = "new_field";
  while (existingNames.includes(newName)) {
    newName = `new_field_${counter++}`;
  }

  // 在当前字段后插入新字段
  const newField: Field = {
    name: newName,
    type: "u8",
    size: 1,
    description: ""
  };

  list.splice(index + 1, 0, newField);

  // 通知父组件数据更新
  emit('update:data', localData.value);

  openEditor(newField);
};

// 添加子字段
const addChildField = (field: Field) => {
  // 确保字段有fields数组
  if (!field.fields) {
    field.fields = [];
  }

  // 为新字段生成唯一名称
  const existingNames = field.fields.map(f => f.name);
  let counter = 1;
  let newName = "new_field";
  while (existingNames.includes(newName)) {
    newName = `new_field_${counter++}`;
  }

  // 添加新子字段
  const newField: Field = {
    name: newName,
    type: "u8",
    size: 1,
    description: ""
  };

  field.fields.push(newField);

  console.log("localData", localData.value);

  // 通知父组件数据更新
  emit('update:data', localData.value);
};
</script>

<template>
  <ul class="tree">
    <li v-for="(field, index) in localData" :key="`${field.name}-${index}`">
      <!-- 折叠按钮 -->
      <span v-if="field.type === 'object' || field.type === 'array'"
            class="toggle"
            @click="expanded[field.name + index] = !expanded[field.name + index]">
        {{ expanded[field.name + index] !== false ? "▼" : "▶" }}
      </span>

      <!-- 字段信息 -->
      <span class="field-name" @click="openEditor(field)">
        {{ field.name }}
      </span>
      <span class="field-type">({{ field.type }})</span>
      <span v-if="field.size" class="field-size"> - {{ field.size }} bytes</span>
      <span v-if="field.type==='array'" class="field-count"> [count: {{ field.count_from }}]</span>
      <span v-if="field.description" class="field-description"> - {{ field.description }}</span>

      <!-- 操作按钮 -->
      <el-button
          v-if="props.editMode"
          circle
          class="btn-add-sibling"
          size="small"
          title="添加同级字段"
          type="primary"
          @click="addSiblingField(localData, index)"
      >
        ➕
      </el-button>
      <el-button
          v-if="props.editMode &&  (field.type === 'object' || field.type === 'array')"
          circle
          class="btn-add-child"
          size="small"
          title="添加子字段"
          type="success"
          @click="addChildField(field)"
      >
        ➕
      </el-button>
      <el-button
          v-if="props.editMode"
          circle
          class="btn-delete"
          size="small"
          title="删除字段"
          type="danger"
          @click="removeField(localData, index)"
      >
        🗑
      </el-button>

      <!-- 递归子项 -->
      <ProtocolTreeEditor
          v-if="(field.type === 'object' || field.type === 'array') && expanded[field.name + index] !== false"
          :data="field.fields || []"
          :edit-mode="props.editMode"
          @update:data="(updatedFields: Field[]) => { 
            field.fields = updatedFields; 
            emit('update:data', localData);
          }"
      />
    </li>
  </ul>

  <!-- 编辑弹窗 -->
  <el-dialog v-model="editDialogVisible" title="编辑字段" width="400px">
    <el-form label-width="80px">
      <el-form-item label="名称">
        <el-input v-model="form.name"/>
      </el-form-item>

      <el-form-item label="类型">
        <el-select v-model="form.type">
          <el-option label="u8" value="u8"/>
          <el-option label="u16" value="u16"/>
          <el-option label="u32" value="u32"/>
          <el-option label="array" value="array"/>
          <el-option label="string" value="string"/>
          <el-option label="bytes" value="bytes"/>
          <el-option label="greedyBytes" value="greedyBytes"/>
          <el-option label="object" value="object"/>
        </el-select>
      </el-form-item>

      <el-form-item v-if="form.type !== 'object' && form.type !== 'array' &&  form.type !== 'greedyBytes'"
                    label="字节数">
        <el-input-number v-model="form.size" :disabled="form.type == 'u8' || form.type == 'u16' || form.type == 'u32'"
                         :min="1"/>
      </el-form-item>

      <el-form-item v-if="form.type==='array'" label="Count">
        <el-select v-model="form.count_from" placeholder="由哪个字段决定数量">
          <el-option
              v-for="f in currentParentFields"
              :key="f.name"
              :disabled="f.name === form.name"
              :label="f.name"
              :value="f.name"
          />
        </el-select>
      </el-form-item>

      <el-form-item label="描述">
        <el-input v-model="form.description" :rows="2" placeholder="请输入字段描述" type="textarea"/>
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="editDialogVisible=false">取消</el-button>
      <el-button type="primary" @click="saveField">保存</el-button>
    </template>
  </el-dialog>
</template>

<style scoped>
.tree {
  list-style: none;
  padding-left: 14px;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  overflow-y: auto;
  margin: 0;
  padding-right: 10px;
}

/* 美化滚动条 */
.tree::-webkit-scrollbar {
  width: 8px;
}

.tree::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.tree::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

.tree::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

.tree > li {
  padding: 6px 0;
  border-bottom: 1px solid #f0f0f0;
}

.toggle {
  cursor: pointer;
  margin-right: 8px;
  font-size: 12px;
  color: #606266;
  user-select: none;
}

.toggle:hover {
  color: #409eff;
}

.field-name {
  font-weight: 600;
  cursor: pointer;
  margin-right: 5px;
  padding: 2px 4px;
  border-radius: 3px;
  transition: all 0.2s;
  color: #303133;
}

.field-name:hover {
  background-color: #ecf5ff;
  color: #409eff;
}

.field-type {
  color: #606266;
  font-size: 13px;
  margin-right: 5px;
  background-color: #f5f7fa;
  padding: 1px 6px;
  border-radius: 4px;
}

.field-size,
.field-count,
.field-description {
  color: #909399;
  font-size: 12px;
  margin-right: 8px;
}

.field-description {
  font-style: italic;
  color: #67c23a;
  background-color: #f0f9ff;
  padding: 1px 6px;
  border-radius: 4px;
}

.btn-add-sibling,
.btn-delete,
.btn-add-child {
  margin-left: 5px;
  font-size: 12px;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s;
}

.btn-add-sibling:hover {
  background-color: #f0f9ff;
}

.btn-delete:hover {
  background-color: #fef0f0;
}

.btn-add-child:hover {
  background-color: #ecf5ff;
}
</style>
